package com.xpower.service;

import com.xpower.demo.ServiceAInterface;
import com.xpower.demo.User;
import feign.hystrix.FallbackFactory;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.stereotype.Component;

//import org.springframework.web.bind.annotation.PathVariable;
//import org.springframework.web.bind.annotation.RequestBody;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RequestMethod;
//import org.springframework.web.bind.annotation.RequestParam;

// 这个FeignClient里面的名字，就是你要调用的那个服务的名字
// 什么叫做声明式的方式，就是不用写代码，直接接口 +注解就搞定了，直接就可以访问别的服务
// 你用了feign之后，说实话，我提前给你剧透一下，spring cloud直接将feign和ribbon整合在一起了
// feign + ribbon + eureka都是整合在一起的
// feign发起请求的时候，都是会交给ribbon的LoadBalancer去进行负载均衡的
// 我们会感觉到，跟之前研究的ribbon整合eureka的负载均衡的原理还不是太一样，我们后面通过源码来看看
// feign + ribbon + eureka是如何整合在一起的

// 疑问来了，我希望的是说，ServiceB要调用ServiceA
// 我希望的是说，我连这个下面的一堆接口都不用自己定义，ServiceA直接提供给我这一票东东
// 这里其实是有重复性的劳动在里面的，其实每个接口的一堆定义和注解，都是由ServiceA搞定就可以了
// 不需要ServiceB重复的定义一遍

// 我只是说，我要访问ServiceA，但是人家ServiceA里面定义了哪些接口，哪些参数，都不用你管了
// 这里不用ServiceB把接口的定义重新写一遍了，直接用人家jar包里提供的就ok了
@FeignClient(value = "ServiceA", fallbackFactory = ServiceAClient.ServiceAClientFallbackFactory.class)
public interface ServiceAClient extends ServiceAInterface {

    @Component
    class ServiceAClientFallbackFactory implements FallbackFactory<ServiceAClient> {
        ServiceAClient serviceAClient = new ServiceAClient() {
            @Override
            public String sayHello(Long id, String name, Integer age) {
                System.out.println("sayHello 降级");
                return null;
            }

            @Override
            public String createUser(User user) {
                System.out.println("createUser 降级");
                return null;
            }

            @Override
            public String updateUser(Long id, User user) {
                System.out.println("updateUser 降级");
                return null;
            }

            @Override
            public String deleteUser(Long id) {
                System.out.println("deleteUser 降级");
                return null;
            }

            @Override
            public User getById(Long id) {
                System.out.println("getById 降级");
                return null;
            }
        };

        @Override
        public ServiceAClient create(Throwable cause) {

            return serviceAClient;
        }
    }

//	@RequestMapping(value = "/user/sayHello/{id}", method = RequestMethod.GET)
//	String sayHello(@PathVariable("id") Long id,
//			@RequestParam("name") String name,
//			@RequestParam("age") Integer age);
//
//	@RequestMapping(value = "/user/", method = RequestMethod.POST)
//	String createUser(@RequestBody User user);
//
//	@RequestMapping(value = "/user/{id}", method = RequestMethod.PUT)
//	String updateUser(@PathVariable("id") Long id, @RequestBody User user);
//
//	@RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
//	String deleteUser(@PathVariable("id") Long id);
//
//	@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
//	User getById(@PathVariable("id") Long id);

}